from flask import abort, jsonify
from flask import current_app
from flask import g
from flask import request
from flask import session

from info import db
from info.models import User, News, Comment
from info.utils.common import user_login_data
from info.utils.response_code import RET
from . import news_detail_blu
from flask import render_template


@news_detail_blu.route("/<int:news_id>")
@user_login_data
def news_detail(news_id):
    user = g.user
    try:
        from info import constants
        news_click = News.query.order_by(News.clicks.desc()).limit(constants.CLICK_RANK_MAX_NEWS)
    except Exception as e:
        current_app.logger.error(e)
    try:
        news = News.query.get(news_id)
    except Exception as e:
        current_app.logger.error(e)
        abort(404)
    if not news:
        abort(404)
    news.clicks += 1
    is_collected = False
    if user:
        if news in user.collection_news:
            is_collected = True
    try:
        db.session.commit()
    except Exception as e:
        db.session.rollback()
        current_app.logger.error(e)
    comments = []
    try:
        comments = Comment.query.filter(Comment.news_id==news_id).order_by(Comment.create_time.desc()).all()
    except Exception as e:
        current_app.logger.error(e)
    comments_list = []
    for i in comments:
        comments_list.append(i.to_dict())
    data = {"user": user.to_dict() if user else None,"news_click":news_click,"news":news.to_dict(),"is_collected":is_collected,"comments": comments_list}
    return render_template("news/detail.html", data=data)


@news_detail_blu.route("/news_collect", methods=['POST'])
@user_login_data
def news_collect():
    # 1、获取登录用户信息(没登录不能收藏和取消收藏)
    user = g.user
    if not user:
        return jsonify(errno=RET.SESSIONERR, errmsg="用户未登录")
    # 2、接收客户端发送过来的参数（news_id，action为collect表示要执行收藏，也可以是cancel_collect表示要执行取消收藏）
    data_dict = request.json  # post请求用json
    news_id = data_dict.get("news_id")
    action = data_dict.get("action")

    # 3、判空
    if not news_id:
        return jsonify(errno=RET.PARAMERR, errmsg="参数错误")

    if action not in ("collect", "cancel_collect"):
        return jsonify(errno=RET.PARAMERR, errmsg="参数错误")

    # 4、查询新闻，判断是否存在
    try:
        news = News.query.get(news_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="查询数据失败")

    if not news:
        return jsonify(errno=RET.NODATA, errmsg="新闻不存在")

    # 5、收藏或者取消收藏
    if action == "collect":
        # 收藏新闻
        # flask操作模型属性的时候，可以使用列表的操作来完成数据的追加和移除
        user.collection_news.append(news)
    else:
        # 取消收藏新闻
        user.collection_news.remove(news)

    try:
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        db.session.rollback()
        return jsonify(errno=RET.DBERR, errmsg="数据库操作失败")

    # 6、返回成功的响应
    return jsonify(errno=RET.OK, errmsg="操作成功")

    # 1、获取登录用户信息


@news_detail_blu.route("/news_comment", methods=["POST"])
@user_login_data
def news_comment():
    user = g.user
    if not user:
        return jsonify(errno=RET.SESSIONERR, errmsg="用户未登录")
    # 2、接收参数
    news_id = request.json.get("news_id")
    comment_str = request.json.get("comment")
    parent_id = request.json.get("parent_id")
    # 3、判空
    if not all([news_id,comment_str]):
        return jsonify(errno=RET.PARAMERR,errmsg="参数错误")
    # 4、查询新闻，并判断是否存在
    try:
        news = News.query.get(news_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR,errmsg="数据库查询失败")
    if not news:
        return jsonify(errno=RET.NODATA,errmsg="该新闻不存在")
    # 5、初始化一个评论模型，添加属性   (如果有parent_id这个参数，也要添加这个属性)
    comment = Comment()
    comment.news_id = news_id
    comment.user_id = user.id
    comment.content = comment_str
    if parent_id:
        comment.parent_id = parent_id
    # 6、添加到数据库
    try:
        db.session.add(comment)
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        db.session.rollback()
        return jsonify(errno=RET.DBERR,errmsg="数据库操作失败")
    # 7、返回成功的响应（并把这个评论模型对象转成字典返回给前端，前端需要展示评论相关数据）
    return jsonify(errno=RET.OK,errmsg="操作成功",data=comment.to_dict())


@news_detail_blu.route("/comment_like", methods=["POST"])
@user_login_data
def comment_like():
    """

    处理 点赞 请求
    处理 取消点赞 请求

    参数：  action     comment_id

    1, 获取用户登陆信息，  如果获取不到(None)，则表示没有登录， 就return
    2, 获取参数
    3, 判空校验
    4, 根据action  的值是 add  或者 remove  来执行对应的 点赞 或者 取消点赞
    5, 返回操作成功
    """

    # 1, 获取用户登录信息，   如果获取不到(None)，则表示没有登录， 就return
    user = g.user
    if not user:
        return jsonify(errno=RET.SESSIONERR, errmsg="用户未登录")
    # 2, 获取参数
    data_dict = request.json
    comment_id = data_dict.get("comment_id")
    action = data_dict.get("action")
    # 3, 判空，校验
    if not all([comment_id, action]):
        return jsonify(errno=RET.PARAMERR, errmsg="参数错误")
    if action not in ("add", "remove"):
        return jsonify(errno=RET.PARAMERR, errmsg="参数错误")

    try:
        comment = Comment.query.get(comment_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="数据库查询错误")

    if not comment:
        return jsonify(errno=RET.NODATA, errmsg="没有这条评论")
    # 4,  根据action  的值是 add  或者 remove  来执行对应的 点赞 或者 取消点赞
    if action == "add":
        # 执行点赞操作
        user.like_comments.append(comment)
        comment.like_count += 1
    else:
        # 执行取消点赞操作
        user.like_comments.remove(comment)
        comment.like_count -= 1

    try:
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        db.session.rollback()
        return jsonify(errno=RET.DBERR, errmsg="数据库操作失败")

    # 5, 返回操作成功
    return jsonify(errno=RET.OK, errmsg="操作成功")
